﻿using System;
using System.Data.SQLite;
using System.Linq;
using CompactMapper.Orm.Extensions;
using CompactMapper.Orm.UnitOfWork.Mappings;
using CompactMapper.Orm.UnitOfWork.Mappings.Meta.PropertyInfos.Columns;

namespace CompactMapper.Orm.UnitOfWork.Commands.Criteria
{
    internal abstract class Criterion
    {
        public abstract String Clause();
        public abstract SQLiteParameter SQLiteParameter();
    }

    internal abstract class Criterion<T> : Criterion
    {
        protected static Type PersistedType;
        protected static Column[] Columns;
        protected readonly string PropertyName;
        protected readonly object TargetValue;
        private readonly String _sql;


        protected Criterion(Queries.Criterion<T> criterion, TablesTree tablesTree)
        {
            if (PersistedType == null)
            {
                PersistedType = typeof (T);
            }
            if (Columns == null)
            {
                Columns = tablesTree.GetTable<T>().Meta.Columns.ToArray();
            }

            PropertyName = criterion.PropertyName;
            TargetValue = criterion.PropertyValue;
            _sql = ToSql();
        }

        public override SQLiteParameter SQLiteParameter()
        {
            var parameter = new SQLiteParameter
                                {
                                    ParameterName = PropertyName.ToSqlValue(),
                                    Value = TargetValue
                                };
            return parameter;
        }

        public override string Clause()
        {
            return _sql;
        }

        protected abstract string ToSql();
    }
}